# -*- coding:utf-8 -*-
import json
from django.db.models import Q
from rest_framework.viewsets import ModelViewSet
from rest_framework.views import APIView
from django.db.transaction import atomic

from Apps.User.models import User
from Apps.System.filters.menuFilter import MenuFilter
from Apps.System.models import Role, Menu
from Apps.System.ser.menu_ser import MenuSer
from Apps.common.response import SuccessResponse, ErrorResponse

from Apps.util.request_util import setCreateUser, setModifyUser

import logging

logger = logging.getLogger('django')


class DelRole(APIView):
    @atomic()
    def post(self, request, *args, **kwargs):
        Role.objects.filter(id__in=request.data).delete()
        return SuccessResponse("12345")


class MenuView(ModelViewSet):
    queryset = Menu.objects.filter(status=True).all()
    serializer_class = MenuSer
    filter_class = MenuFilter
    authentication_classes = []

    # 创建菜单
    def create(self, request, *args, **kwargs):
        request = setCreateUser(request)
        try:
            if Menu.objects.get(perms__exact=request.data["perms"]):
                logger.info("权限字符已存在")
                return ErrorResponse("权限字符已存在")
        except Exception as e:
            logger.info(e)
            pass

        if request.data["permType"] != 'button':
            request.data["is_directory"] = True

        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        self.perform_create(serializer)
        return SuccessResponse("新增成功")

    # 更新菜单
    def update(self, request, *args, **kwargs):
        request = setModifyUser(request)
        partial = kwargs.pop('partial', True)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        return SuccessResponse("修改成功")

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        if instance.is_directory and instance.parentMenu is None:
            permType = 'first'
        elif not instance.is_directory:
            permType = 'button'
        else:
            permType = 'second'
        resultDate = {
            "permType": permType,
            "parentMenu": instance.parentMenu,
            "icon": instance.icon,
            "name": instance.name,
            "web_path": instance.web_path,
            "perms": instance.perms,
            "sort": instance.sort,
            "status": instance.status,
            "description": instance.description
        }
        return SuccessResponse(resultDate)

    # 删除菜单
    def destroy(self, request, *args, **kwargs):
        # 删除时，判断是否有子菜单未删除
        instance = self.get_object()
        queryset = self.get_queryset()
        for item in queryset:
            if item.parentMenu is not None and instance.id in item.parentMenu:
                logger.info(instance.id)
                return ErrorResponse("当前菜单有子菜单，不可删除")

        # instance.delete()
        logger.info("删除的权限================")
        logger.info(instance.id)
        return SuccessResponse("删除成功")

    # 列表展示菜单数据
    def list(self, request, *args, **kwargs):
        queryset = self.filter_queryset(self.get_queryset())
        logger.info(queryset)
        serializer = self.get_serializer(queryset, many=True)
        querysetData = serializer.data

        """
        通过关键词查询的菜单，需要获取对应的上级菜单
        """
        ResponseData = []
        for item in querysetData:
            # 查询出来有上级菜单，判断对应上级菜单在不在列表内，不在则添加到列表内
            if item["parentMenu"] is not None:
                logger.info("id")
                parentMenus = Menu.objects.filter(id__in=item["parentMenu"]).all()
                parentSerializerData = self.get_serializer(parentMenus, many=True)
                for parentMenu in parentSerializerData.data:
                    if parentMenu not in querysetData:
                        querysetData.append(parentMenu)

        for item in querysetData:
            # 一级菜单
            if item["parentMenu"] is None:
                ResponseData.append(item)

        for item in querysetData:
            if item["parentMenu"] is not None and len(item["parentMenu"]) == 1:
                for menu in ResponseData:
                    if item["parentMenu"][0] == menu["id"]:
                        if not menu.get("children", []):
                            menu["children"] = []
                            menu["children"].append(item)
                        else:
                            menu["children"].append(item)

        for item in querysetData:
            if item["parentMenu"] is not None and len(item["parentMenu"]) == 2:
                for menu in ResponseData:
                    if item["parentMenu"][0] == menu["id"]:
                        for childrenMenu in menu["children"]:
                            if item["parentMenu"][1] == childrenMenu["id"]:
                                if not childrenMenu.get("children", []):
                                    childrenMenu["children"] = []
                                    childrenMenu["children"].append(item)
                                else:
                                    childrenMenu["children"].append(item)

        logger.info("返回的权限============")
        logger.info(querysetData)
        logger.info(ResponseData)
        return SuccessResponse(ResponseData)


class getParentMenuView(APIView):
    """
    获取上级级菜单，新建菜单时使用
    """

    def get(self, request, *args, **kwargs):
        menuType = request.query_params["permType"]

        resultParentMenu = []

        FirstMenuQueryset = Menu.objects.filter(is_directory=True, status=True, parentMenu__isnull=True).all()
        for MenuItem in FirstMenuQueryset:
            resultParentMenu.append({
                'value': MenuItem.id,
                'label': MenuItem.name
            })

        if menuType == 'second':
            return SuccessResponse(resultParentMenu)

        if menuType == 'button':
            MenuQuerysetSecond = Menu.objects.filter(is_directory=True, status=True, parentMenu__isnull=False).all()
            logger.info("获取按钮的菜单==============")
            logger.info(MenuQuerysetSecond)
            for MenuItem in MenuQuerysetSecond:
                for firstMenuItem in resultParentMenu:
                    if MenuItem.parentMenu[-1] == firstMenuItem.get("value"):
                        if not firstMenuItem.get("children", None):
                            firstMenuItem["children"] = []
                            firstMenuItem["children"].append({
                                'value': MenuItem.id,
                                'label': MenuItem.name
                            })
                        else:
                            firstMenuItem["children"].append({
                                'value': MenuItem.id,
                                'label': MenuItem.name
                            })

            return SuccessResponse(resultParentMenu)


class getMenuTree(APIView):
    """
    新建角色时使用
    """

    def get(self, request, *args, **kwargs):
        queryset = Menu.objects.all()

        serializer = getMenuTreeSer(queryset, many=True)

        ResponseData = []

        for item in serializer.data:
            if item["menuType"] == '0':
                item["children"] = []
                item["label"] = item["name"]
                # item["menuType"] = "一级菜单"
                ResponseData.append(item)

        for item in serializer.data:
            if item["menuType"] == '1':
                for firstMenu in ResponseData:
                    if firstMenu['id'] == item["parentId"]:
                        item["children"] = []
                        item["label"] = item["name"]
                        # item["menuType"] = "二级菜单"
                        firstMenu["children"].append(item)

        for item in serializer.data:
            if item["menuType"] == '2':
                for firstMenu in ResponseData:
                    for secondMenu in firstMenu["children"]:
                        if secondMenu["id"] == item["parentId"]:
                            # item["menuType"] = "按钮"
                            item["label"] = item["name"]
                            secondMenu["children"].append(item)

        return SuccessResponse(ResponseData)


class getMenuByRoleView(APIView):

    def get(self, request, *args, **kwargs):
        role_id = request.query_params["role_id"]

        menus = Role.objects.get(pk=role_id).menu_set.all()
        menuList = []
        for item in menus:
            menuList.append(item.id)

        role = Role.objects.get(pk=role_id)

        responseDict = {
            "roleName": role.roleName,
            "remark": role.remark,
            "menuList": menuList

        }

        return SuccessResponse(responseDict)


class MenuByRoleView(APIView):
    """
        菜单和角色关系表
    """

    # 新增角色菜单
    def post(self, request, *args, **kwargs):

        roleId = request.data["roleId"]
        menuIds = request.data["menuData"]

        def setMenu(ro: Role):
            MenuSet = Menu.objects.filter(id__in=menuIds)
            # for item in MenuSet:
            #     item.role.set([ro])
            # pass

            ro.menu_set.set(MenuSet)

        if roleId:
            # 有角色
            role = Role.objects.get(id=roleId)
            setMenu(role)
        else:

            # 没有角色，先创建角色
            serializer = PostRoleSer(data={"roleName": request.data["roleName"],
                                           "remark": request.data.get("remark", "")
                                           })
            serializer.is_valid(raise_exception=True)
            role = serializer.save()
            setMenu(role)
        return SuccessResponse("保存成功")


class setRoleByUserView(APIView):
    """
    用户分配角色
    """

    def post(self, request, *args, **kwargs):
        # 保存数据
        userId = request.data["userId"]
        roleIds = request.data["roleIds"]
        user = User.objects.get(id=userId)
        roles = Role.objects.filter(id__in=roleIds)
        user.role_set.set(roles)

        return SuccessResponse("保存成功")


class getRoleByUserView(APIView):
    """
        查询用户的分配角色captcha_captchastore
    """

    def post(self, request, *args, **kwargs):
        userId = request.data.get("userId", None)
        responseDateList = []

        roles = Role.objects.all().values("id", "roleName")

        if userId:
            userRoles = Role.objects.filter(user__id=userId).all().values("id", "roleName")
            for role in roles:
                if role in userRoles:
                    role["checked"] = True
                responseDateList.append(role)
        responseDateList = roles

        return SuccessResponse(responseDateList)


class getRouteByUser(APIView):
    def get(self, request, *args, **kwargs):
        user = request.user

        """
        roles = UserRole.objects.filter(user_id=user.id).values("role_id")
        # [{'role_id': '1930036e-aeda-4c68-9975-bbdc6899601d'},{},...]

        # 获取当前用户所有角色的菜单ID（取并集）
        # 第一次遍历，获取按钮的二级菜单
        menuList = []
        for role in roles:
            menus = RoleMenu.objects.filter(role_id=role["role_id"]).values("menu__id", "menu__parentId",
                                                                            "menu__menuType")
            for menusId in menus:
                if menusId["menu__id"] not in menuList:
                    menuList.append(menusId["menu__id"])
                if menusId["menu__parentId"] not in menuList:
                    menuList.append(menusId["menu__parentId"])

        # 第二次遍历，获取按钮的一级菜单
        menus = Menu.objects.filter(id__in=menuList).values("id", "parentId", "menuType")
        for menusId in menus:
            if menusId["id"] not in menuList:
                menuList.append(menusId["id"])
            if menusId["parentId"] not in menuList:
                menuList.append(menusId["parentId"])

        # 超级管理员获取所有菜单
        if user.is_superuser:
            allMenu = Menu.objects.all()
        else:
            allMenu = Menu.objects.filter(id__in=menuList).all()

        # 用来添加到路由中
        Routes = []
        for menu in allMenu:
            if menu.menuType in ["1"]:
                Routes.append({
                    "path": menu.web_path,
                    "name": menu.web_path,
                    "meta": {
                        "icon": menu.icon,
                        "title": menu.name
                    },
                    "component": menu.component_path
                })

        # {
        #           id: 1,
        #           icon: 'el-icon-folder',
        #           title: '项目管理',
        #           children: [{
        #             id: 11,
        #             path: "/management",
        #             icon: 'el-icon-aim',
        #             title: '项目列表'
        #           }, {
        #             id: 12,
        #             path: "/setting_management",
        #             icon: 'el-icon-aim',
        #             title: '项目设置'
        #           },
        #           ]
        #         }

        # 用来添加到菜单中
        sidebarRouters = []
        webPath = []

        serializer = getMenuSidebarSer(allMenu, many=True)

        for item in serializer.data:
            if item["menuType"] == '0':
                item["children"] = []
                item["title"] = item["name"]
                item["path"] = item["web_path"]
                # item["menuType"] = "一级菜单"
                sidebarRouters.append(item)

        for item in serializer.data:
            if item["menuType"] == '1':
                for firstMenu in sidebarRouters:
                    if firstMenu['id'] == item["parentId"]:
                        item["title"] = item["name"]
                        item["path"] = item["web_path"]
                        # item["menuType"] = "二级菜单"
                        firstMenu["children"].append(item)

                        webPath.append(item["web_path"])

        # buttonPermission 按钮权限
        buttonPermission = []
        for item in serializer.data:
            if item["menuType"] == '2':
                buttonPermission.append(item["perms"])
        # 返回
        response = {
            "webPath": webPath,
            "routes": Routes,
            "sidebarRouters": sidebarRouters,
            "buttonPermission": buttonPermission
        }
        # logger.info(response)

        """
        # 查询用户的所有角色
        roles = user.role_set.all()
        logger.info(roles)
        logger.info(user.is_superuser)
        # 查询对应角色的菜单
        if user.is_superuser:
            menus = Menu.objects.all()
        else:
            menus = Menu.objects.filter(role__in=[roles]).all()

        # 用来添加到路由中
        Routes = []
        for menu in menus:
            if menu.menuType in ["1"]:
                Routes.append({
                    "path": menu.web_path,
                    "name": menu.web_path,
                    "meta": {
                        "icon": menu.icon,
                        "title": menu.name
                    },
                    "component": menu.component_path
                })

        # {
        #           id: 1,
        #           icon: 'el-icon-folder',
        #           title: '项目管理',
        #           children: [{
        #             id: 11,
        #             path: "/management",
        #             icon: 'el-icon-aim',
        #             title: '项目列表'
        #           }, {
        #             id: 12,
        #             path: "/setting_management",
        #             icon: 'el-icon-aim',
        #             title: '项目设置'
        #           },
        #           ]
        #         }

        # 用来添加到菜单中
        sidebarRouters = []
        webPath = []

        serializer = getMenuSidebarSer(menus, many=True)

        for item in serializer.data:
            if item["menuType"] == '0':
                item["children"] = []
                item["title"] = item["name"]
                item["path"] = item["web_path"]
                # item["menuType"] = "一级菜单"
                sidebarRouters.append(item)

        for item in serializer.data:
            if item["menuType"] == '1':
                for firstMenu in sidebarRouters:
                    if firstMenu['id'] == item["parentId"]:
                        item["title"] = item["name"]
                        item["path"] = item["web_path"]
                        # item["menuType"] = "二级菜单"
                        firstMenu["children"].append(item)

                        webPath.append(item["web_path"])

        # buttonPermission 按钮权限
        buttonPermission = []
        for item in serializer.data:
            if item["menuType"] == '2':
                buttonPermission.append(item["perms"])

        # 返回
        response = {
            "webPath": webPath,
            "routes": Routes,
            "sidebarRouters": sidebarRouters,
            "buttonPermission": buttonPermission
        }
        return SuccessResponse(response)
